package pub.pjoc.config.aop;

import pub.pjoc.cache.CacheService;
import pub.pjoc.cache.vo.Cache;
import pub.pjoc.config.ConfigReloadable;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author xiongyingqi
 * @since 16-6-8 下午5:40
 */
public class ConfigServiceInterceptor implements ConfigReloadable {
  private static final Logger logger = LoggerFactory
      .getLogger(ConfigServiceInterceptor.class);
  /**
   * configGroup在redis内的前缀
   */
  private static final String CONFIG_GROUP_PREFIX = "config_group:";

  private CacheService cacheService;

//    public ConfigServiceInterceptor(CacheService cacheService) {
//        this.cacheService = cacheService;
//    }

  public String getConfig(ProceedingJoinPoint call, String configGroup, String configName)
      throws Throwable {
    String cacheGroup = buildConfigGroup(configGroup);

    String value = null;
    try {
      value = cacheService.getCacheValue(cacheGroup, configName);
    } catch (Exception e) {
      logger.error("", e);
    }
    if (value == null) {
      String configValue = null;
      try {
        configValue = (String) call.proceed();
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Got configValue: {} by configGroup: {}, configName: {} from configService",
              configValue, configGroup, configName);
        }
      } catch (Throwable throwable) {
        logger.error("", throwable);
      }
      if (configValue == null) {
        return null;
      }
      if (logger.isDebugEnabled()) {
        logger.debug("Putting configGroup: {} configName: [} configValue: {} to cache.",
            configGroup, configName, configValue);
      }
      try {
        cacheService.setCache(new Cache(cacheGroup, configName, configValue));
      } catch (Exception e) {
        logger.error("", e);
      }
      return configValue;
    }

    if (logger.isDebugEnabled()) {
      logger.debug("Got config value: {} by ConfigGroup: {} and ConfigName: {}", value,
          cacheGroup, configName);
    }
    return value;
  }

  private static String buildConfigGroup(String configGroup) {
    return CONFIG_GROUP_PREFIX + configGroup;
  }


  public String setConfig(ProceedingJoinPoint proceedingJoinPoint, String configGroup,
                          String configName, String configValue) {
    String proceed = null;
    try {
      proceed = (String) proceedingJoinPoint.proceed();
    } catch (Throwable throwable) {
      logger.error("", throwable);
    }
    String cacheGroup = buildConfigGroup(configGroup);
    try {
      cacheService.setCache(new Cache(cacheGroup, configName, configValue));
    } catch (Exception e) {
      logger.error("", e);
    }
    return proceed;
  }

  public boolean clearCache(ProceedingJoinPoint proceedingJoinPoint) {
    try {
      proceedingJoinPoint.proceed();
    } catch (Throwable throwable) {
      logger.error("", throwable);
    }
    try {
      cacheService.clearCachesByGroupPrefix(CONFIG_GROUP_PREFIX);
    } catch (Exception e) {
      logger.error("", e);
    }
    return true;
  }

  public CacheService getCacheService() {
    return cacheService;
  }

  public void setCacheService(CacheService cacheService) {
    this.cacheService = cacheService;
  }

  @Override
  public boolean reloadConfig() {
    try {
      cacheService.clearCachesByGroupPrefix(CONFIG_GROUP_PREFIX);
    } catch (Exception e) {
      logger.error("", e);
      return false;
    }
    return true;
  }
}
